package org.fle4y.app.server.database;

import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Vector;

/**
 * author : xiehui<br>
 * company : northking <br>
 * Create at: 2012-6-19<br>
 * @version : 1.0<br>
 * mailto:flexie@foxmail.com<br>
 *  Description : 表达式
 */
@SuppressWarnings("unchecked")
public class Expression {

	final static int VALUE = 1, COLUMN = 2, QUERY = 3, TRUE = 4, VALUELIST = 5,
			ASTERIX = 6, FUNCTION = 7;
	final static int NEGATE = 9, ADD = 10, SUBTRACT = 11, MULTIPLY = 12,
			DIVIDE = 14, CONCAT = 15;
	final static int NOT = 20, EQUAL = 21, BIGGER_EQUAL = 22, BIGGER = 23,
			SMALLER = 24, SMALLER_EQUAL = 25, NOT_EQUAL = 26, LIKE = 27,
			AND = 28, OR = 29, IN = 30, EXISTS = 31;
	final static int COUNT = 40, SUM = 41, MIN = 42, MAX = 43, AVG = 44;
	final static int IFNULL = 60, CONVERT = 61, CASEWHEN = 62;
	final static int PLUS = 100, OPEN = 101, CLOSE = 102, SELECT = 103,
			COMMA = 104, STRINGCONCAT = 105, BETWEEN = 106, CAST = 107,
			END = 108;
	private int iType;
	private Expression eArg, eArg2;
	private Object oData;
	private Hashtable hList;
	private int iDataType;
	private Select sSelect;
	private char cLikeEscape;
	private String sTable, sColumn;
	private int iColumn;
	private String sAlias;
	private boolean bDescending; 
	public Expression(Expression e) {
		iType = e.iType;
		iDataType = e.iDataType;
		eArg = e.eArg;
		eArg2 = e.eArg2;
		cLikeEscape = e.cLikeEscape;
		sSelect = e.sSelect;
	}

	public Expression(Select s) {
		iType = QUERY;
		sSelect = s;
	}



	public Expression(Vector v) {
		iType = VALUELIST;
		iDataType = Column.VARCHAR;
		int len = v.size();
		hList = new Hashtable(len);
		for (int i = 0; i < len; i++) {
			Object o = v.elementAt(i);
			if (o != null) {
				hList.put(o, this);
			}
		}
	}

	public Expression(int type, Expression e, Expression e2) {
		iType = type;
		eArg = e;
		eArg2 = e2;
	}

	public Expression(String table, String column) {
		sTable = table;
		if (column == null) {
			iType = ASTERIX;
		} else {
			iType = COLUMN;
			sColumn = column;
		}
	}

	public Expression(int datatype, Object o) {
		iType = VALUE;
		iDataType = datatype;
		oData = o;
	}

	public void setLikeEscape(char c) {
		cLikeEscape = c;
	}


	public void setDataType(int type) {
		iDataType = type;
	}

	public void setTrue() {
		iType = TRUE;
	}

	public boolean isAggregate() {
		if (iType == COUNT || iType == MAX || iType == MIN || iType == SUM
				|| iType == AVG) {
			return true;
		}
		return false;
	}

	public void setDescending() {
		bDescending = true;
	}
	
	public boolean isDescending() {
		return bDescending;
	}
	
	public void setAlias(String s) {
		sAlias = s;
	}
	
	public String getAlias() {
		if (sAlias != null) {
			return sAlias;
		}
		if (iType == VALUE) {
			return "";
		}
		if (iType == COLUMN) {
			return sColumn;
		}
		return "";
	}

	public int getType() {
		return iType;
	}
	
	int getColumnNr() {
		return iColumn;
	}

	public Expression getArg() {
		return eArg;
	}

	public Expression getArg2() {
		return eArg2;
	}


	public void checkResolved() throws SQLException {
		if (eArg != null) {
			eArg.checkResolved();
		}

		if (eArg2 != null) {
			eArg2.checkResolved();
		}
	}

	public boolean isResolved() {
		if (iType == VALUE) {
			return true;
		}
		return false;
	}

	public static boolean isCompare(int i) {
		switch (i) {

		case EQUAL:

		case BIGGER_EQUAL:

		case BIGGER:

		case SMALLER:

		case SMALLER_EQUAL:

		case NOT_EQUAL:
			return true;
		}

		return false;
	}

	public String getTableName() {
		if (iType == ASTERIX) {
			return sTable;
		}
		return "";
	}

	public String getColumnName() {
		return getAlias();
	}

	public void swapCondition() throws SQLException {
	int i = EQUAL;

	switch (iType) {

	case BIGGER_EQUAL:
	    i = SMALLER_EQUAL;

	    break;

	case SMALLER_EQUAL:
	    i = BIGGER_EQUAL;

	    break;

	case SMALLER:
	    i = BIGGER;

	    break;

	case BIGGER:
	    i = SMALLER;

	    break;

	case EQUAL:
	    break;

	default:
	    throw new SQLException("未知错误！");
	}

	iType = i;

	Expression e = eArg;

	eArg = eArg2;
	eArg2 = e;
    }
}
